package com.baymax.study.redisson.infrastructure.locks.configure;

import com.baymax.study.redisson.infrastructure.locks.aop.LockAspect;
import com.baymax.study.redisson.infrastructure.locks.lock.DistributedLockRedissonImpl;
import com.baymax.study.redisson.infrastructure.locks.lock.DistributedReadLockImpl;
import com.baymax.study.redisson.infrastructure.locks.lock.DistributedWriteLockImpl;
import com.baymax.study.redisson.infrastructure.locks.utils.GlobalLockUtils;
import jodd.util.StringUtil;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SentinelServersConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@AutoConfigureBefore(LockConfig.class)
@ConditionalOnProperty(name = {"commons.global.lock.enable"}, havingValue = "true")
@Import({LockConfig.class, DistributedLockRedissonImpl.class, DistributedWriteLockImpl.class, DistributedReadLockImpl.class, GlobalLockUtils.class})
public class GlobalLockAutoConfigure {
    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalLockAutoConfigure.class);

    @Autowired
    private LockConfig lockConfig;

    @Bean
    @ConditionalOnMissingBean(RedissonClient.class)
    public RedissonClient redissonClient() {
        LOGGER.info("初始化 Redisson");
        Config config = new Config();
        config.setLockWatchdogTimeout(10000);
        if (lockConfig.getCloud()) {
            if (lockConfig.getPassword() != null && lockConfig.getPassword().length() > 1) {
                config.useReplicatedServers().setScanInterval(2000).setPassword(lockConfig.getPassword()).setDatabase(2).setMasterConnectionMinimumIdleSize(2).setMasterConnectionPoolSize(lockConfig.getConnectPoolSize()).setSlaveConnectionPoolSize(lockConfig.getConnectPoolSize()).setSlaveConnectionMinimumIdleSize(2).setPingConnectionInterval(0).setTimeout(5000)
                    //                        .addNodeAddress("redis://r-8vby0pzqiscurfn6nzpd.redis.zhangbei.rds.aliyuncs.com:36378");
                    .addNodeAddress(lockConfig.getSingle());
            } else {
                config.useReplicatedServers().setScanInterval(1000) // 主节点变化扫描间隔时间
                    //可以用"rediss://"来启用SSL连接
                    .addNodeAddress(lockConfig.getSingle()).setMasterConnectionPoolSize(lockConfig.getConnectPoolSize()).setSlaveConnectionPoolSize(lockConfig.getConnectPoolSize());
            }
        } else if (lockConfig.getMaster() != null && !lockConfig.getMaster().isEmpty()) {
            config.useMasterSlaveServers()
                //可以用"rediss://"来启用SSL连接
                .setMasterAddress("redis://" + lockConfig.getMaster()).setPassword(lockConfig.getPassword()).setMasterConnectionPoolSize(5).setMasterConnectionMinimumIdleSize(3).setSlaveConnectionPoolSize(5).setSlaveConnectionMinimumIdleSize(3);
            if (StringUtil.isNotEmpty(lockConfig.getSlave())) {
                String[] split = lockConfig.getSlave().split(",");
                for (String slaveAddr : split) {
                    config.useMasterSlaveServers().addSlaveAddress("redis://" + slaveAddr);
                }
            }

        } else if (lockConfig.getSentinel() != null && lockConfig.getSentinel().size() > 0) {
            SentinelServersConfig sentinelServersConfig = config.useSentinelServers();
            sentinelServersConfig.setMasterName(lockConfig.getMaster());
            sentinelServersConfig.setMasterConnectionMinimumIdleSize(5);
            sentinelServersConfig.setDatabase(lockConfig.getDb());
            sentinelServersConfig.setSlaveConnectionMinimumIdleSize(5);
            for (String s : lockConfig.getSentinel()) {
                sentinelServersConfig.addSentinelAddress(s);
            }
        } else if (lockConfig.getPassword() != null && lockConfig.getPassword().length() > 1) {
            config.useSingleServer().setDatabase(lockConfig.getDb()).setConnectionPoolSize(lockConfig.getConnectPoolSize()).setConnectionMinimumIdleSize(2).setAddress(lockConfig.getSingle()).setPassword(lockConfig.getPassword());
        } else {
            config.useSingleServer().setDatabase(lockConfig.getDb()).setConnectionPoolSize(lockConfig.getConnectPoolSize()).setConnectionMinimumIdleSize(2).setAddress(lockConfig.getSingle());
        }
        return Redisson.create(config);
    }

    @Bean
    public LockAspect lockAspect() {
        return new LockAspect();
    }
}
